<?php

namespace App\Http\Controllers\Api\Buz;

use App\Http\Controllers\Api\BuzBaseController;
use App\Lib\Code;
use App\Models\PlatUserApp;
use App\Models\RechargeOrder;
use App\Repositories\Criteria\AppCriteria;
use App\Repositories\Criteria\AuthUserCriteria;
use App\Repositories\Criteria\MchNoCriteria;
use App\Repositories\Criteria\OrderStatusCriteria;
use App\Repositories\Criteria\TimeFilterCriteria;
use App\Repositories\Eloquent\PlatUserAppRepository;
use App\Repositories\Eloquent\RechargeOrderRepository;
use App\Services\ApiResponseService;
use App\Validators\Buz\AppValidator;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class AppController extends Controller
{
    protected $appRepository;
    protected $orderRepository;

    public function __construct(PlatUserAppRepository $platUserAppRepository,
                                RechargeOrderRepository $rechargeOrderRepository)
    {
        $this->appRepository = $platUserAppRepository;
        $this->orderRepository = $rechargeOrderRepository;
        $this->appRepository->pushCriteria(AuthUserCriteria::class);
        $this->orderRepository->pushCriteria(AuthUserCriteria::class);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
        $items = $this->appRepository->all(['id', 'app_id', 'name', 'classify']);
        foreach ($items as & $item) {
            $orderModel = $item->rechargeOrders()->today()->where('order_status', 1)->select('order_amt');
            $item['today_total_amt'] = $orderModel->sum('order_amt');
            $item['today_total_order'] = $orderModel->count();
        }
        return ApiResponseService::returnData($items);
    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request        $request
     * @param \App\Validators\Buz\AppValidator $appValidator
     *
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request, AppValidator $appValidator)
    {
        //
        $data = $request->all(array_keys($appValidator->getRules('create')));
        $appValidator->with($data)->passesOrFail('create');
        $uid = Auth::user()->id;
        $data += compact('uid');
        $this->appRepository->create($data + compact('uid'));
        return ApiResponseService::success(Code::SUCCESS);
    }

    /**
     * Display the specified resource.
     *
     * @param  string                         $id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
        $item = $this->appRepository->findWhere(['app_id' => $id])->first();
        $data = [];
        if ($item) {
            $data['name'] = $item->name;
            $data['app_id'] = $item->app_id;
            $data['classify'] = $item->classify;
            $data['domain'] = $item->domain;
            $data['icp'] = $item->icp;
            if ($item->classify != 0) $data['app_signature'] = $item->app_signature;
            if ($item->classify == 1) $data['app_package'] = $item->app_package;
            $data['status'] = $item->status;
            $data['notify_url'] = $item->notify_url;
            $data['created_at'] = $item->created_at->toDateTimeString();
            if ($item->status == 2) $data['remark'] = $item->remark;
        }
        return ApiResponseService::returnData($data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request        $request
     * @param \App\Validators\Buz\AppValidator $appValidator
     * @param  string                             $id
     *
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request,
                           AppValidator $appValidator,
                           $id)
    {
        //
        $data = $request->all(array_keys($appValidator->getRules('update')));
        $appValidator->with($data)->passesOrFail('update');
        $app = $this->appRepository->findWhere(['app_id' => $id])->first();
        if ( ! $app) {
            return ApiResponseService::showError(Code::NOTFOUND);
        }
        $app->update($data);
        return ApiResponseService::success(Code::SUCCESS);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  string  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
        $this->appRepository->deleteWhere(['app_id' => $id]);
        return ApiResponseService::success(Code::SUCCESS);
    }


    public function rechargeOrders(Request $request, $id)
    {
        $payment = $request->input('payment') ? : 'all';
        $order_status = $request->input('order_status') ? : 99;
        $mch_no = $request->input('merchant_no') ?? '';
        $pageSize = $request->input('pageSize') ?? 20;
        $app = $this->appRepository->findWhere(['app_id' => $id])->first();
        $this->orderRepository->pushCriteria(new AppCriteria($app->id));
        $this->orderRepository->pushCriteria(new TimeFilterCriteria($request));
        $this->orderRepository->pushCriteria(new OrderStatusCriteria($order_status, 'order_status'));
        $this->orderRepository->pushCriteria(new MchNoCriteria($mch_no));
        $orders = $this->orderRepository
            ->orderBy('created_at', 'desc')
            ->whereHas('payment', function ($query) use ($payment) {
                if ($payment != 'all') {
                    $query->where('identify', $payment);
                }
            })->with(['payment' => function ($query) use ($payment){
                    $query->select('id', 'identify', 'name');
            }, 'notify' => function ($query) {
                $query->select('order_id', 'status');
            }]);
        $total = clone $orders;
        $total = $total->get();
        $orders =   $orders->paginate($pageSize, ['id', 'plat_no', 'merchant_no', 'order_amt', 'order_settle', 'order_status', 'pm_id', 'created_at']);
        $items = $orders->items();
        $page_total_amt = $total->sum('order_amt');
        $total = $total->where('order_status', 1);
        $page_done_amt = $total->sum('order_amt');
        $page_done_settle = $total->where('is_settle', 1)->sum('order_settle');
        $page_wait_settle = $total->where('is_settle', 0)->sum('order_settle');
        foreach ($items as &$item) {
            $item->order_settle = $item->order_status == 1 ? $item->order_settle : '-'; 
        }
        $page_total_amt = number_format($page_total_amt, 2, '.', '');
        $page_done_amt = number_format($page_done_amt, 2, '.', '');
        $page_done_settle = number_format($page_done_settle, 2, '.', '');
        $page_wait_settle = number_format($page_wait_settle, 2, '.', '');
        return ApiResponseService::returnData($orders->toArray() + compact('page_total_amt', 'page_done_amt', 'page_done_settle', 'page_wait_settle'));
    }
}
